package org.biojava.services.das.servlets;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.zip.GZIPOutputStream;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;

import org.biojava.dasobert.das.Capabilities;
import org.biojava.dasobert.das.DasSpec;
import org.biojava.dasobert.das2.io.DasSourceWriter;
import org.biojava.dasobert.das2.io.DasSourceWriterImpl;
import org.biojava.dasobert.dasregistry.Das1Source;
import org.biojava.dasobert.dasregistry.DasCoordinateSystem;
import org.biojava.dasobert.dasregistry.DasSource;
import org.biojava.dasobert.dasregistry.DasValidationResult;
import org.biojava.services.das.dao.RegistryUser;
import org.biojava.services.das.registry.ConfigBean;
import org.biojava.services.das.registry.DasRegistrySql;
import org.biojava.utils.xml.XMLWriter;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import dasregistry.security.Authenticate;
import dasregistry.validation.Validator;

/**
 * Servlet implementation class Validate
 */
public class AuthenticationServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	Authenticate authenticate;

	private String returnUrl="";
	private String isSecure="";

	public AuthenticationServlet() {
		super();
		BeanFactory ctx = (new ClassPathXmlApplicationContext("SpringDAO.xml"));
		authenticate = (Authenticate) ctx.getBean("authenticate");
	}

	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		ServletContext context = getServletContext();
		returnUrl = context.getInitParameter("returnUrl");//where to return to with  the token 
		isSecure = context.getInitParameter("isSecure");//should be true of false. we don't have https on laptop development so this is a way to say
		//if we are checking for https or not
		}
	
	
	
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		authenticationMethod(request, response);


	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		
		authenticationMethod(request, response);

	}

	private void authenticationMethod(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String protocol = request.getProtocol();
		System.out.println("protocol="+protocol);
		if(isSecure.equals("true")){
			//if not secure ie. on mac then just don't do any of this https checking
			//if we are on live or sandbox isSecure should be true then lets check the protocol is https
			//do this by checking the header X-is-ssl=1 which is set by the front ends
			String sslHeader=request.getHeader("X-is-ssl")+"";
			if(!sslHeader.equals("1")){
			PrintWriter writer = response.getWriter();
			System.out.println("Needs to be an https request for this request");
			writer.println("Needs to be an https request for this request");//https only sends a get after redirect when https url requested through front ends
			return ;
			}
		}
		String email = request.getParameter("email")+"";
		System.out.println("email=" + email);
		String pass = request.getParameter("password")+"";
		System.out.println("password=" + pass);
		HttpSession session = request.getSession();
		RequestDispatcher dispatcher = request
				.getRequestDispatcher("login.jsp");
		
		
		String newPass=request.getParameter("new_pass")+"";
		System.out.println("new_pass="+newPass);
		if(newPass!=null && session.getAttribute("email")!=null && !newPass.equals("")){
			
			if(session.getAttribute("possibleNewUser")!=null){
				//this is a user who wants to register and has clicked on the link sent to their email so create them so we can then update their password
				RegistryUser newUser=(RegistryUser) session.getAttribute("possibleNewUser");			
				int alertUser=0;
				int bogStandardUser=1;
				if(newUser.isAlertMe()){
					alertUser=1;
				}
				
				authenticate.addUserWithPass(newUser.getEmail(), newPass, newUser.getOpenID(), bogStandardUser, alertUser);
				response.sendRedirect(returnUrl+"thanksForRegistering.jsp");//redirect here so we get normal http not https after the user has gone through authentication, also page refreshes will not do a post again!
				//RequestDispatcher thanks=request.getRequestDispatcher(returnUrl+"thanksForRegistering.jsp");
				//thanks.forward(request, response);
				return;
			}
			
			//we have a logged in user who wants to change their password
			System.out.println("session email="+(String)session.getAttribute("email")+" newPass="+newPass);
			String message=authenticate.updatePassword((String)session.getAttribute("email"), newPass );
			if(!message.equals("")){
				
				session.setAttribute("message",message);
				dispatcher.forward(request, response);
			}
			response.sendRedirect(returnUrl+"PasswordChanged.jsp");//redirect here so we get normal http not https after the user has gone through authentication, also page refreshes will not do a post again!
			//RequestDispatcher success=request.getRequestDispatcher(returnUrl+"PasswordChanged.jsp");
			//success.forward(request, response);
			return;
		}
		
		
		if (email == null || email.equals("") || pass == null
				|| pass.equals("")) {
			session.setAttribute("message",
					"you need to enter an email and a password");
			session.removeAttribute("email");
			dispatcher.forward(request, response);
			return;
		}
		// test user exists
		if (authenticate.userExists(email)) {
			// if authenticated set the email in the session
			System.out.println("email user exists, email="+email);
			if (authenticate.authenticate(email, pass)) {
				System.out.println("setting attribute email in authenticate");
				session.setAttribute("email", email);
				//successful login
				//need to redirect to a http request not https so it flips it back to normal http and doesnt make many requests per page
				response.sendRedirect(returnUrl+"successLogin.jsp");
				return;
				
			}else{
				session.setAttribute("message", "<font color=\"red\">The password for the user identified by this email is not correct</font>");
			}
		} else {
			session.setAttribute("message", "user with email " + email
					+ " does not exist");
		}

		dispatcher.forward(request, response);

		// PrintWriter writer = response.getWriter();
		// writer.println("got authentication request");
	}

}
